﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml;

namespace ShootSearch.Util.Serializers
{
    /// <summary>
    /// Serialize or Deserialize the object to or form the xml 
    /// </summary>
    public class XmlFormatter
    {
        //private static XmlWriterSettings setting = null;
        public static string CleanXml(string xml)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);
            return doc.DocumentElement.InnerXml;
            //return doc.InnerXml;
        }


        public static string ToXml(object obj)
        {
            if (obj == null) return string.Empty;
            MemoryStream stream = new MemoryStream();
            TextWriter tw = new StreamWriter(stream, Encoding.UTF8);

            try
            {
                XmlSerializer serializer = new XmlSerializer(obj.GetType());
                XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();
                xmlns.Add(String.Empty, String.Empty);
                serializer.Serialize(tw, obj,xmlns);
                stream.Position = 0;
                StreamReader sr = new StreamReader(stream, Encoding.UTF8);
                string r = sr.ReadToEnd();
                stream.Close();
                return r;          
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                return ex.ToString();
            }
        }

        public static void ToXml(XmlWriter writer, object obj)
        {
            if (obj == null) return;
            try
            {
                XmlSerializer serializer = new XmlSerializer(obj.GetType());
                XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();
                xmlns.Add(String.Empty, String.Empty);
                serializer.Serialize(writer, obj, xmlns);            
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);              
            }
        }


        private static string UTF8ByteArrayToString(byte[] characters)
        {
            UTF8Encoding encoding = new UTF8Encoding();
            String constructedString = encoding.GetString(characters);
            return (constructedString);
        }

        public static void ToXmlFile(object obj, string fileName)
        {
            try
            {
                if (CheckDirectory(fileName))
                {
                    File.WriteAllText(fileName, ToXml(obj),Encoding.UTF8);
                }

            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }

        private static bool CheckDirectory(string fileName)
        {
            FileInfo fi = new FileInfo(fileName);
            if (!fi.Directory.Exists)
            {
                try
                {
                    fi.Directory.Create();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex);
                    return false;
                }
            } 
            return true;
        }

        public static object FromXml(XmlReader reader, Type type)
        {
            try
            {            
                XmlSerializer serializer = new XmlSerializer(type,"");
                object obj = serializer.Deserialize(reader);
                return obj;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
            return null;
        }

        public static object FromXml(string xml, Type type)
        {
            try
            {                
                TextReader tr = new StringReader(xml);
                XmlTextReader reader = new XmlTextReader(tr);
                reader.Normalization = false;
                XmlSerializer serializer = new XmlSerializer(type,"");
                object obj = serializer.Deserialize(reader);                
                tr.Close();
                reader.Close();
                return obj;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
            return null;
        }

        public static object FromFile(string fileName, Type type)
        {
            if (!File.Exists(fileName))
            {
                return null;
            }
            try
            {
                if (!File.Exists(fileName)) return null;
                string xml = File.ReadAllText(fileName,Encoding.UTF8);
                return FromXml(xml, type);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
            return null;
        }

        /// <summary>
        /// 静态方法Serialize,将一个对象序列化为一个文件
        /// </summary>
        /// <param name="data"></param>
        /// <param name="filePath"></param>
        public static void SerializeBinary(object data, string fileName)
        {
            try
            {
                if (!CheckDirectory(fileName))
                {
                    return;
                }

                FileStream fs = new FileStream(fileName, FileMode.Create);
                //打开文件
                //StreamWriter fs = new StreamWriter(filePath, false);
                try
                {
                    // 创建其支持存储区为内存的流
                    //byte[] data;
                    //MemoryStream streamMemory = new MemoryStream();
                    // 以二进制格式将对象或整个连接对象图形序列化或反序列化
                    BinaryFormatter formater = new BinaryFormatter();
                    //将这个对象序列化到内存流中
                    formater.Serialize(fs, data);
                    //先转换为字符串的形式
                    //string binaryData = Convert.ToBase64String(streamMemory.GetBuffer());
                    //StreamReader sr = new StreamReader(streamMemory);

                    //将数据 写入到文件
                    //fs.Write(binaryData);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    fs.Flush();
                    fs.Close();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 反序列化,从文件序列化一个对象
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static object DeserializeBinary(string fileName)
        {
            object data = new object();
            try
            {
                if (!File.Exists(fileName)) return data;

                FileStream fs = new FileStream(fileName, FileMode.Open);
                //打开文件
                //StreamReader sr = new StreamReader(filePath);
                try
                {
                    byte[] bytes = new byte[fs.Length];
                    fs.Read(bytes, 0, bytes.Length);
                    BinaryFormatter formatter = new BinaryFormatter();
              
                    //反序列化为对象
                    data = formatter.Deserialize(new MemoryStream(bytes));//streamMemory);
                }
                catch
                {
                    // 不能得到数据,设为空
                    data = null;
                }
                finally
                {
                    //最后关闭文件
                    fs.Close();
                }

            }
            catch
            {
                // 不能得到数据,设为空
                data = null;
            }
            //返回数据
            return data;
        }



    }
}
